package com.fancy.application.sys.org.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fancy.application.common.exception.FancyRuntimeException;
import com.fancy.application.common.service.impl.BaseService;
import com.fancy.application.common.utils.JwtUtil;
import com.fancy.application.common.utils.UserUtil;
import com.fancy.application.sys.auth.vo.LoginForm;
import com.fancy.application.sys.org.entity.SysOrgModel;
import com.fancy.application.sys.org.entity.SysOrgPerson;
import com.fancy.application.sys.org.mapper.SysOrgPersonMapper;
import com.fancy.application.sys.org.service.ISysOrgDeptService;
import com.fancy.application.sys.org.service.ISysOrgPersonService;
import com.fancy.application.sys.org.service.ISysOrgPostPersonRelationService;
import com.fancy.application.sys.org.util.SaltUtil;
import com.fancy.application.sys.org.vo.PasswordVo;
import com.fancy.application.sys.org.vo.SysOrgPersonVo;
import com.fancy.application.sys.permission.service.ISysPermissionRoleResRelService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.InputStreamResource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.List;

/**
* fancycode自动生成v1.0
* @author wison
* 2019-09-07
*/
@Log4j2
@Service("sysOrgPersonService")
public class SysOrgPersonServiceImpl extends BaseService<SysOrgPersonMapper,SysOrgPerson> implements ISysOrgPersonService {

    @Resource
    private ISysOrgDeptService sysOrgDeptService;

    @Resource
    private ISysOrgPostPersonRelationService sysOrgPostPersonRelationService;

    @Resource
    private JwtUtil jwtUtil;
    @Resource
    private ISysPermissionRoleResRelService sysPermissionRoleResRelService;

    /**
     *  附件存放基础路径
     */
    @Value("${fancy.att.resources}")
    private String fdAttPath;


    @Override
    @Transactional(rollbackFor=Exception.class)
    public void savePerson(SysOrgPersonVo sysOrgPersonVo) {
        SysOrgPerson sysOrgPerson = new SysOrgPerson();
        BeanUtil.copyProperties(sysOrgPersonVo,sysOrgPerson, CopyOptions.create().ignoreNullValue());

        String fdId = sysOrgPerson.getFdId();
        if(StrUtil.isEmpty(fdId)){          //新增
            String password = sysOrgPerson.getFdPassword();
            String salt= SaltUtil.getSaltStr();
            sysOrgPerson.setFdSalt(salt);
            if(StrUtil.isEmpty(password)){
                password = "123456";
            }
            password = SaltUtil.generatePassword(password,sysOrgPerson.getCredentialsSalt());

            sysOrgPerson.setFdPassword(password);
        }else{      //更新
            String password = sysOrgPerson.getFdPassword();
            SysOrgPerson person = this.getById(sysOrgPerson.getFdId());
            if(StrUtil.isNotEmpty(password)){
                password = SaltUtil.generatePassword(password,person.getCredentialsSalt());
                sysOrgPerson.setFdPassword(password);
            }
        }
        this.saveOrUpdate(sysOrgPerson);
        //保存岗位的关系
        sysOrgPostPersonRelationService.saveRelations(sysOrgPerson.getFdId(),sysOrgPersonVo.getFdPostIds(),sysOrgPersonVo.getFdPostNames());
    }

    @Override
    public SysOrgPerson getPersonByLoginInfo(LoginForm loginForm) {
        String userName = loginForm.getUserName();
        String password = loginForm.getPassword();
        SysOrgPerson person = this.getOne(new QueryWrapper<SysOrgPerson>().eq("fd_login_name",userName).eq("fd_is_avaliable",true));
        if(person!=null){
            password = SaltUtil.generatePassword(password,person.getCredentialsSalt());
            if(StrUtil.equals(password,person.getFdPassword())){
                return person;
            }
        }
        return null;
    }

    @Override
    public SysOrgPerson getPersonByToken(String token) {
        String loginName = jwtUtil.getUsername(token);
        return getPersonByLoginName(loginName);
    }



    private SysOrgPerson getPersonByLoginName(String loginName) {
        QueryWrapper<SysOrgPerson> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("fd_is_avaliable",true).eq("fd_login_name",loginName);
        return this.getOne(queryWrapper);
    }

    @Override
    public boolean saveOrUpdate(SysOrgPerson sysOrgPerson){
        String fdParentId = sysOrgPerson.getFdParentId();
        if(StrUtil.isEmpty(sysOrgPerson.getFdId())){
            sysOrgPerson.setFdId(IdUtil.simpleUUID());
        }
        String fdHierarchyId = "";
        if(StrUtil.isNotEmpty(fdParentId)) {
            SysOrgModel model = sysOrgDeptService.getById(fdParentId);
            fdHierarchyId = model.getFdHierarchyId();
        }
        if(StrUtil.isEmpty(fdHierarchyId)){
            fdHierarchyId += sysOrgPerson.getFdId();
        }else{
            fdHierarchyId = fdHierarchyId+"x"+sysOrgPerson.getFdId();
        }
        sysOrgPerson.setFdHierarchyId(fdHierarchyId);
        return super.saveOrUpdate(sysOrgPerson);
    }

    /**
     * 保存用户头像
     * @param file
     */
    @Override
    public void saveUserImg(MultipartFile file) throws IOException {
        String savePath = File.separator+"userImg"+File.separator+ UserUtil.getCurrentUser().getFdLoginName()+".jpg";
        BufferedOutputStream out = FileUtil.getOutputStream(fdAttPath+savePath);
        IoUtil.copy(file.getInputStream(), out, IoUtil.DEFAULT_BUFFER_SIZE);
    }

    /**
     * 获取头像
     * @param file
     * @param loginName
     * @return
     */
    @Override
    public InputStreamResource getUserImg(File file, String loginName) {
        InputStreamResource resource = null;
        if(file.exists()){
            try {
                resource = new InputStreamResource(new FileInputStream(file));
            } catch (Exception e) {
                log.warn("无法获取{}的头像",UserUtil.getCurrentUser().getFdLoginName());
                e.printStackTrace();
            }
        }
        return resource;
    }

    /**
     * 修改密码
     * 先确认老密码是否和数据库一致,如果一致,再修改新密码
     * @param passwordVo
     */
    @Override
    public void resetPwd(PasswordVo passwordVo) {
        String userId = passwordVo.getUserId();
        SysOrgPerson person = null;
        if(StrUtil.isNotBlank(userId)){
            person = this.getById(userId);
        }else{
            person = UserUtil.getCurrentUser();
        }

        String currentPassword = person.getFdPassword();
        String oldPassword = SaltUtil.generatePassword(passwordVo.getOldPassword(),person.getCredentialsSalt());
        if(StrUtil.equals(oldPassword,currentPassword)){
            String newPassword = SaltUtil.generatePassword(passwordVo.getNewPassword(),person.getCredentialsSalt());
            person.setFdPassword(newPassword);
            this.updateById(person);
        }else{
            throw new FancyRuntimeException("当前密码验证错误,请重新输入");
        }
    }

    /**
     * 管理员修改密码
     * 无需确认老密码是否一致
     *
     */
    public void superResetPwd(PasswordVo passwordVo) {
        SysOrgPerson person = null;
        if(StrUtil.isNotBlank(passwordVo.getUserId())){
            person = this.getById(passwordVo.getUserId());
        }else{
            throw new FancyRuntimeException("无法找到对应用户!");
        }
        String newPassword = SaltUtil.generatePassword(passwordVo.getNewPassword(),person.getCredentialsSalt());
        person.setFdPassword(newPassword);
        this.updateById(person);
    }

    @Override
    public void addPostInfo(SysOrgPersonVo sysOrgPersonVo) {
        String userId = sysOrgPersonVo.getFdId();
        sysOrgPostPersonRelationService.getRelationInfoByUserId(userId,sysOrgPersonVo);
    }

    @Override
    public List<String> getResByUserId(String fdId) {
        return sysPermissionRoleResRelService.findResByPersonId(fdId);
    }

}
